﻿using Blm.Utils.Extensions;
using Blm.Utils.Security;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using VisionCloud.Domain.Common;
using VisionCloud.Web;
using Xunit;
using Xunit.Abstractions;

namespace UnitTest.Tests.Controllers.Extranal
{
    /// <summary>
    /// 单元测试基础类
    /// </summary>
    public class ExtranalTestBase : IClassFixture<CustomWebApplicationFactory<Startup>>
    {
        protected readonly ITestOutputHelper outPut;
        protected readonly HttpClient httpClient;
        private readonly static string userName = "fms";
        private readonly static string secret = "6JsfdSL3LPOadflj1LKKfsf22dfmbvgc";

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="outPut"></param>
        public ExtranalTestBase(ITestOutputHelper outPut)
        {
            var app = new WebApplicationFactory<Startup>().WithWebHostBuilder(builder =>
            {
                //设定环境变量
                builder.UseContentRoot("..\\..\\..\\..\\..\\VisionCloud.Web\\bin\\Debug\\netcoreapp3.1");
                builder.UseWebRoot("..\\..\\..\\..\\VisionCloud.Web\\wwwroot");
                builder.UseEnvironment("Local");
            });

            this.outPut = outPut;
            this.httpClient = app.CreateClient();
        }

        /// <summary>
        /// post请求
        /// </summary>
        /// <param name="action">单元测试接口的路由</param>
        /// <param name="body">请求内容</param>
        /// <returns></returns>
        public async Task<ApiResult> PostData(string action, dynamic body)
        {
            var bodyString = JsonConvert.SerializeObject(body);
            HttpClientBuildAuth(action, bodyString);
            var content = new StringContent(bodyString);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var data = await httpClient.PostAsync(action, content);
            var result = await data.Content.ReadAsStringAsync();
            outPut.WriteLine(result);
            var apiReturn = JsonConvert.DeserializeObject<ApiResult>(result);

            return apiReturn;
        }

        /// <summary>
        /// get请求
        /// </summary>
        /// <param name="action">单元测试接口的路由</param>
        /// <returns></returns>
        public async Task<ApiResult> GetData(string action)
        {
            var path = action.Split("?")[0];
            HttpClientBuildAuth(path, string.Empty);
            var data = await httpClient.GetAsync(action);
            var result = await data.Content.ReadAsStringAsync();
            outPut.WriteLine(result);
            var apiReturn = JsonConvert.DeserializeObject<ApiResult>(result);

            return apiReturn;
        }

        private void HttpClientBuildAuth(string path, string body)
        {
            try
            {
                if (!path.StartsWith("/"))
                {
                    path = $"/{path}";
                }
                var timestamp = DateTime.Now.ToUnixDateTime();
                var planText = $"api={path}&version=1.0&date={timestamp}&username={userName}&SHA-256={SecurityHelper.GetSHA256Str(body)}";
                var cipherText = SecurityHelper.GetHmacSHA256Str(planText, secret);
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"hmac username={userName},signature={cipherText}");
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Date", timestamp.ToString());
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("appVersion", "1.0");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }      
        }
    }
}